/**
 * 我们有一个 Door 的抽象概念，它具备两个行为 open() 和 close()，至于其他的具体类可以通过使用 extends 使用抽象类方式定义 Door 或者 Implements 使用接口方式定义 Door，
 * 这里发现两者并没有什么很大的差异。
 * 但是现在如果我们需要门具有报警的功能，那么该如何实现呢？
 * 解决方案一：给 Door 增加一个报警方法:clarm();(错误的方案)这种方法违反了面向对象设计中的一个核心原则 ISP (Interface Segregation Principle)—见批注，
 * 在 Door 的定义中把 Door 概念本身固有的行为方法和另外一个概念"报警器"的行为方 法混在了一起。
 * 这样引起的一个问题是那些仅仅依赖于 Door 这个概念的模块会因为”报警器”这个概念的改变而改变，反之依然。
 * 解决方案二
 * 既然 open()、close() 和alarm() 属于两个不同的概念，那么我们依据 ISP 原则将它们分开定义在两个代表两个
 * 不同概念的抽象类里面，定义的方式有三种：
 * 1、两个都使用抽象类来定义。（java不支持多继承，所以此方案不可行）
 * 2、两个都使用接口来定义。（如果使用第二种：那么就反映了两个问题：1、我们可能没有理解清楚问题域，AlarmDoor 在概念本质上到底是门还报警器。2、如果我们对问题域的理解没有问题，
 * 比如我们在分析时确定了 AlarmDoor 在本质上概念是一致的，那么我们在设计时就没有正确的反映出我们的设计意图因为你使用了两个接口来进行定义，
 * 他们概念的定义并不能够反映上述含义。）
 * 3、一个使用抽象类定义，一个是用接口定义。（正确）（如果我们对问题域的理解是这样的：AlarmDoor 本质上 Door，但同时它也拥有报警的行为功能，
 * 这个时候我们使用第三种方案恰好可以阐述我们的设计意图。AlarmDoor 本质是们，所以对于这个概念我们使用抽象类来定义，同时 AlarmDoor 具备报警功能，
 * 说明它能够完成报警概念中定义的行为功能）
 * 这种实现方式基本上能够明确的反映出我们对于问题领域的理解，正确的揭示我们的设计意图。其实抽象类表示的是"is-a"关系，接口表示的是"like-a"关系，
 * 大家在选择时可以作为一个依据，当然这是建立在对问题领域的理解上的，比如：如果我们认为 AlarmDoor 在概念本质上是报警器, 同时又具有 Door 的功能，那么上述的定义方式就要反过来了
 */
/**
 * @author admin
 *
 */
package javaBase.abstractRunable.AlarmDoor;